import MenuItem from "./MenuItem";
import Dropdown from "../Dropdown";
import { PropType, defineComponent, getCurrentInstance, inject, onMounted, provide, ref, watch, watchEffect } from "vue";
import { MenuContext, MenuTreeContext } from ".";

export interface SubMenuProps {
    name?: string,
    align?: "bottom" | "right" | "bottomLeft" | "bottomRight" | "rightTop" | "left" | "leftTop",
    title?: any,
    padding?: number,
    parent?: any
    icon?: any
}

export default defineComponent({
    name: 'SubMenu',
    props: {
        name: {type: String as PropType<SubMenuProps['name']>},
        align: {type: String as PropType<SubMenuProps['align']>},
        title: {type: String as PropType<SubMenuProps['title']>},
        padding: {type: Number as PropType<SubMenuProps['padding']>},
        parent: {type: Object as PropType<SubMenuProps['parent']>},
        icon: {type: Object as PropType<SubMenuProps['icon']>},
    },
    setup (props: SubMenuProps, {slots, expose}) {
        if (!props.name) {
            console.warn("SubMenu need name prop");
        }

        const ctx: any = inject(MenuContext, {});
        const treeCtx: any = inject(MenuTreeContext, {});
        const isOpened = ref(false);
        const parentPadding = treeCtx.parent ? treeCtx.parent.padding : 0;
        const padding = ref(parentPadding + 16);
        const listEle = ref();

        const classList = ref({});

        watch(() => isOpened.value, (isOpen) => {
            if (!listEle.value) {
                return;
            }
            listEle.value.style.transition = 'none';
            listEle.value.style.height = 'auto';
            const oh = listEle.value.offsetHeight;
            listEle.value.style.transition = '';
            if (isOpen) {
                listEle.value.style.height = '0px';
                setTimeout(() => {
                    listEle.value.style.height = oh + 'px';
                });
                setTimeout(() => {
                    listEle.value.style.height = 'auto';
                }, 250);
            } else {
                listEle.value.style.height = oh + 'px';
                setTimeout(() => {
                    listEle.value.style.height = '0px';
                });
            }
        });

        watchEffect(() => {
            const openKeys = ctx.openKeys.value;
            isOpened.value = openKeys[props.name];
            classList.value = ({
                'cm-menu-submenu': true,
                'cm-menu-submenu-open': isOpened.value
            });
        });

        const onSelect = () => {
            ctx?.setOpen(props.name);
        };

        const align = props.align || (ctx?.dir === 'h' ? 'bottom' : 'rightTop');

        const createNode = () => {
            const item = {
                name: props.name,
                parent: null,
                children: [],
                padding: padding.value
            };
            if (ctx && props.name) {
                ctx.treeMap[props.name] = item;
                if (!treeCtx.parentName) {
                    ctx?.tree.push(item);
                } else {
                    const parent = ctx.treeMap[treeCtx.parentName];
                    if (parent) {
                        item.parent = parent;
                        parent.children.push(item);
                    }
                }
            }
            provide(MenuTreeContext, {parentName: props.name, parent: ctx.treeMap[props.name]});
        };
        createNode();

        watchEffect(() => {
            ctx.treeMap[props.name].padding = (ctx.store.min || ctx?.dir === 'h') ? 0 : padding.value;
        });

        return () => ctx.store.min || ctx?.dir === 'h' ? (
            <li class={classList.value}>
                <Dropdown transfer={false} align={align} theme={ctx?.theme} revers={false} menu={<ul class="cm-menu-submenu-list" ref={listEle} x-name={props.name}>{slots.default?.()}</ul>}>
                    <MenuItem icon={props.icon} cert isSubmenuTitle onSelect={onSelect}>
                        {props.title}
                    </MenuItem>
                </Dropdown>
            </li>
        ) : (
            <li class={classList.value}>
                <MenuItem cert icon={props.icon} isSubmenuTitle onSelect={onSelect}>
                    {props.title}
                </MenuItem>
                <ul class="cm-menu-submenu-list" ref={listEle} x-name={props.name}>{slots.default?.()}</ul>
            </li>
        );
    }
});
